package events

import (
	"fmt"
	"gitee.com/zackeus/go-boot/freeswitch/esl/headers"
	"net/textproto"
	"net/url"
	"strings"
)

const (
	EventAll = "ALL"

	// EventStartUp 系统启动
	EventStartUp = "STARTUP"
	// EventShutdown 系统关闭
	EventShutdown = "SHUTDOWN"
	// EventModuleLoad 模块加载
	EventModuleLoad = "MODULE_LOAD"
	// EventModuleUnLoad 模块卸载
	EventModuleUnLoad = "MODULE_UNLOAD"
	// EventHeartBeat FS 心跳事件
	EventHeartBeat = "HEARTBEAT"
	// EventReSchedule 重新安排任务
	EventReSchedule = "RE_SCHEDULE"
	// EventLog 日志
	EventLog = "LOG"
	// EventApi api 回调通知事件
	EventApi = "API"
	// EventBackRoundJob bgapi 回调通知事件
	EventBackRoundJob = "BACKGROUND_JOB"

	// EventChannelCallState 通道呼叫状态
	EventChannelCallState = "CHANNEL_CALLSTATE"
	// EventChannelCreate 通道创建事件
	EventChannelCreate = "CHANNEL_CREATE"
	// EventChannelProgress 通道振铃事件
	EventChannelProgress = "CHANNEL_PROGRESS"
	// EventChannelAnswer 通道应答事件
	EventChannelAnswer = "CHANNEL_ANSWER"
	// EventChannelBridge 通道桥接事件
	EventChannelBridge = "CHANNEL_BRIDGE"
	// EventChannelHangUp 通道挂断事件
	EventChannelHangUp = "CHANNEL_HANGUP"

	// EventRecordStart 录音开始
	EventRecordStart = "RECORD_START"
	// EventRecordStop 录音结束
	EventRecordStop = "RECORD_STOP"

	// EventMediaBugStart ASR启动（连接）成功后
	EventMediaBugStart = "MEDIA_BUG_START"
	// EventDetectedSpeech ASR事件
	EventDetectedSpeech = "DETECTED_SPEECH"

	// ---------------------- 自定义事件 根据 Event-Subclass 区分 ------------------------

	// EventCustom 自定义事件头
	// eg: CUSTOM sofia::sip_user_state
	EventCustom = "CUSTOM"

	// EventSofiaState 终端状态变更事件
	EventSofiaState = "CUSTOM sofia::sip_user_state"
	// EventSofiaRegister 终端注册事件
	EventSofiaRegister = "CUSTOM sofia::register"
	// EventSofiaAttempt 终端注册尝试事件
	EventSofiaAttempt = "CUSTOM sofia::register_attempt"
	// EventSofiaFailure 终端注册失败事件
	EventSofiaFailure = "CUSTOM sofia::register_failure"
	// EventSofiaUnRegister 终端注销事件
	EventSofiaUnRegister = "CUSTOM sofia::unregister"
	// EventSofiaExpire 终端注册过期事件
	EventSofiaExpire = "CUSTOM sofia::expire"

	// EventCallCenter 呼叫中心事件
	EventCallCenter = "CUSTOM callcenter::info"
	// EventIvrKey IVR 按键事件
	EventIvrKey = "CUSTOM ivr::key"
	// EventIvrLog IVR 日志事件
	EventIvrLog = "CUSTOM ivr::log"

	// EventTxFax 发送传真
	EventTxFax = "CUSTOM spandsp::txfaxresult"
	// EventRxFax 接收传真
	EventRxFax = "CUSTOM spandsp::rxfaxresult"
)

type (
	EventListener func(event *Event)

	Event struct {
		Headers textproto.MIMEHeader
		Body    []byte
	}
)

// GetName Helper function that returns the event name header
func (e Event) GetName() string {
	return e.GetHeader(headers.EventName)
}

// HasHeader Helper to check if the Event has a header
func (e Event) HasHeader(header string) bool {
	_, ok := e.Headers[textproto.CanonicalMIMEHeaderKey(header)]
	return ok
}

// GetHeader Helper function that calls e.Header.Get
func (e Event) GetHeader(header string) string {
	value, _ := url.PathUnescape(e.Headers.Get(header))
	return value
}

// String Implement the Stringer interface for pretty printing (%v)
func (e Event) String() string {
	var builder strings.Builder

	eventType := e.GetName()
	if eventType == EventCustom {
		eventType = fmt.Sprintf("%s %s", EventCustom, e.GetHeader(headers.EventSubclass))
	}
	builder.WriteString(fmt.Sprintf("%s\n", eventType))
	for key, values := range e.Headers {
		builder.WriteString(fmt.Sprintf("%s: %#v\n", key, values))
	}
	builder.Write(e.Body)
	return builder.String()
}

// GoString Implement the GoStringer interface for pretty printing (%#v)
func (e Event) GoString() string {
	return e.String()
}
